package stats;

import java.io.File;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;

import database.DbConnection;
import database.DbNames;
import file.ResultFile;

import parser.IupacParser;
import parser.IupacResidue;
import parser.IupacTree;
import utils.TreeTools;

public class ResidueStats {
	
	public ArrayList<String> getSortedSequencesFromDb(String dbName, String querySelect, int sequenceLength)
	{
	IupacParser p= new IupacParser();
	ArrayList<String> sequences = new ArrayList<String>();		
	DbConnection connect = new DbConnection();
	
	int rowsSelect = 0;	
	
	try 
	{			
		/*connect and get data from the database*/
		ResultSet rs = connect.getData(dbName,querySelect);//DbNames.glycosuite, DbNames.querySelectGS
		
		/*for each record in the resultset, parse the sequence*/
		while (rs.next()) {
			String structureId = rs.getString(1);
			String structure = rs.getString(2);
			String glycanType = rs.getString(3);
			
			rowsSelect++;
		    System.out.println(rowsSelect + "/ ID : " + rs.getString(1));
		    
		    long begin = System.nanoTime();
			
			try
			{
				p.setIupacSequence(structure);
				p.setGlycanType(glycanType);
				
				IupacTree tree = p.parse();
				
				for(int i = 0; i<tree.getBranches().size(); i++)
				{
					for(int j = 0; j<tree.getBranches().get(i).getResiduesList().size(); j++)
					{
						IupacResidue res = tree.getBranches().get(i).getResiduesList().get(j);
						
						if(sequenceLength ==1)
						{
							sequences.add(res.getSequence());						
						}
						if(sequenceLength ==2)
						{
							IupacResidue previousRes =  TreeTools.getPreviousResidue(res);;
							String seq = res.getSequence();
							if(previousRes.isTreeRoot())
							{
										
							}
							else
							{
								seq += "<-"+ previousRes.getSequence();						
							}
							sequences.add(seq);

						}
											
					
					}	
				}
			}
			catch(Exception ex)
			{
				System.err.println("Problem parsing the sequence");
				System.err.println(ex.getMessage());
			}
			long end = System.nanoTime();
			System.out.println("Process time [s] : " + (end-begin)*Math.pow(10, -9));
		}
		rs.close();
		connect.getStmtSelect().close();
	} 
	catch (SQLException se) 
	{
		System.err.println(se.getMessage());
	}
	catch (Exception ex) 
	{
		System.err.println(ex.getMessage());
	}
	
	/*sort residues sequences*/
	Collections.sort(sequences);
	
	return sequences;
	}


//	public ArrayList<String> parseSequences(String dbName, String querySelect)
//	{
//	IupacParser p= new IupacParser();
//	String structureId = rs.getString(1);
//	String structure = rs.getString(2);
//	String glycanType = rs.getString(3);
//	ArrayList<String> sequences = new ArrayList<String>();		
//	try
//	{
//		p.setIupacSequence(structure);
//		p.setGlycanType(glycanType);
//		
//		IupacTree tree = p.parse();
//		
//		for(int i = 0; i<tree.getBranches().size(); i++)
//		{
//			for(int j = 0; j<tree.getBranches().get(i).getResiduesList().size(); j++)
//			{
//			sequences.add(tree.getBranches().get(i).getResiduesList().get(j).getSequence());						
//			}	
//		}
//	}
//	catch(Exception ex)
//	{
//		System.err.println("Problem parsing the sequence");
//		System.err.println(ex.getMessage());
//	}
//	}
	

	public ArrayList<String> countOccurences(String dbName, int sequenceLength)
	{
		
		String query = new DbNames().getQuerySelect(dbName); 
		/*count occurrences by type (residue+linkage) in stats array*/
		ArrayList<String> sequences = this.getSortedSequencesFromDb(dbName, query, sequenceLength);
		ArrayList<String> stats = new ArrayList<String>();
		int count = 1;
		for(int n=sequences.size()-1; n>=1; n--)
		{	
			if(sequences.get(n).equals(sequences.get(n-1)))
			{
				count++;
			}
			else
			{
				String result =sequences.get(n)+ ";" + count + "/"  + sequences.size();
				stats.add(result);
				
				count=1;
			}			
		}
		Collections.sort(stats);
		return stats;
	}
	
	public File getStatFile(String dbName, int sequenceLength)
	{
		long beginCompleteUpdate = System.nanoTime();
		long endCompleteUpdate;
		int rowsSelect = 0;
	
		//ResidueStats rStat = new ResidueStats();		
		ArrayList<String> stats = this.countOccurences(dbName,sequenceLength);
		
		/*write result to a file*/
		ResultFile file = new ResultFile("stats" + dbName + "_" + sequenceLength+ "Res" +".txt");
		for(int s=0;s<stats.size();s++)
		{
			file.writeToFile(stats.get(s));
		}
		
		endCompleteUpdate = System.nanoTime();
		
		System.out.println("");
		System.out.println("Process time [s] : " + (endCompleteUpdate-beginCompleteUpdate)*Math.pow(10, -9));
		System.out.println("Rows selected : " + rowsSelect);
	//	System.out.println("Residues translatable : " + sequences.size());
		
		return file.getFile();
		}

	
//	public ArrayList<String> countOccurences(ArrayList<String> sequences)
//	{
//		/*count occurrences by type (residue+linkage) in stats array*/
//		ArrayList<String> stats = new ArrayList<String>();
//		int count = 1;
//		for(int n=sequences.size()-1; n>=1; n--)
//		{	
//			if(sequences.get(n).equals(sequences.get(n-1)))
//			{
//				count++;
//			}
//			else
//			{
//				String result =sequences.get(n)+ ";" + count + "/"  + sequences.size();
//				stats.add(result);
//				
//				count=1;
//			}			
//		}
//		Collections.sort(stats);
//		return stats;
//	}
//	
	
}
